package linkList;

import exceptions.BadDataException;
import exceptions.EmptyLinkedListException;
import exceptions.OutOfLinkedListException;

/**
 * Class representing linked list
 * 
 * @author az
 * 
 */
public class LinkedList implements ILinkedList {

	private Node start;
	private int size;

	/**
	 * Adds a new node in the beginning, filling it with given data.
	 * 
	 * @param data
	 *            - data to be added in the beginning
	 * @throws BadDataException
	 *             - when null is passed
	 */
	public void add(Object data) throws BadDataException {
		if (start == null) {
			start = new Node(data, null);
		} else {
			// create a new node with given data and start as a next
			Node newNode = new Node(data, start);
			start = newNode;
		}
		size++;
	}

	/**
	 * Gets an element of given index.
	 * 
	 * @param index
	 *            - the index of element
	 * @return - the element's data at that position
	 * @throws OutOfLinkedListException
	 *             - when the index is above the size and below 0
	 * @throws EmptyLinkedListException
	 *             - when the list is empty
	 */
	public Object get(int index) throws OutOfLinkedListException,
			EmptyLinkedListException {
		if (start == null)
			throw new EmptyLinkedListException();
		if (index < 0)
			throw new OutOfLinkedListException("Negative index!");
		Node current = start;
		for (int i = 0; i < index; i++) {
			if (current == null) {
				throw new OutOfLinkedListException("No such element!");
			}
			current = current.getNext();
		}

		return current.getData();
	}

	/**
	 * Gets the number of elements in the linked list.
	 * 
	 * @return - int representing this number
	 */
	public int getSize() {
		return size;
	}

	/**
	 * Removes the first element of the linked list.
	 * 
	 * @return - the data in this element
	 * @throws EmptyLinkedListException
	 */
	@Override
	public Object removeFirs() throws EmptyLinkedListException {
		if (start == null) {
			throw new EmptyLinkedListException();
		}
		Object data = start.getData();
		start = start.getNext();
		size--;
		return data;
	}
}
